package cn.net.yugu.doraemon.api.common.model;

import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;

import cn.net.yugu.doraemon.api.common.enums.CommonRestResultCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 兼容原 web-api 的API响应结构体
 *
 * @author xiangzr
 * @version 2023/08/01 20:44:42:42
 */
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class RestResult<T> implements Serializable {

    private static final long serialVersionUID = -2502106816909650192L;

    public static final int OK_CODE = 0;

    private Integer code;
    private String message;

    private T data;

    public boolean isSuccess() {
        return Objects.equals(code, OK_CODE);
    }

    /**
     * 构建无payload的成功响应体
     *
     * @param <T>
     * @return
     */
    public static <T> RestResult<T> buildSuccess() {
        return RestResult.<T>builder()
                .code(CommonRestResultCode.OK_LEGACY.getCode())
                .message(CommonRestResultCode.OK_LEGACY.getDesc())
                .build();
    }

    /**
     * 构建成功响应体
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> RestResult<T> buildSuccess(Optional<T> data) {
        if (data == null || !data.isPresent()) {
            return buildSuccess();
        }
        return buildSuccess(data.get());
    }

    public static <T> RestResult<T> buildSuccess(T data) {
        return RestResult.<T>builder()
                .code(CommonRestResultCode.OK_LEGACY.getCode())
                .data(data)
                .message(CommonRestResultCode.OK_LEGACY.getDesc())
                .build();
    }

    /**
     * 构建失败响应体
     *
     * @param code
     * @param message
     * @return
     */
    public static <T> RestResult<T> buildFail(CommonRestResultCode code, String message) {
        return buildFail(Objects.requireNonNull(code).getCode(), message);
    }

    /**
     * 构建失败响应体
     *
     * @param code
     * @param message
     * @return
     */
    public static <T> RestResult<T> buildFail(Integer code, String message) {
        return RestResult.<T>builder()
                .code(Objects.requireNonNull(code))
                .message(message)
                .build();
    }
}
